package com.mini.framework.record;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Calendar;

public class DefaultAppender implements RecordAppender {
	
	private static final long ONE_DATE_MILLIS = 24 * 60 * 60 *1000;
	
	private String recordPath;
	
	
	private FileChannel fileChannel;
	
	private FileOutputStream fileOut;
	
	private long todayZeroTime;
	
	private RecordFormatter formatter;
	
	
	public DefaultAppender(String recordPath){
		this.recordPath = recordPath;
		formatter = new DefaultFormatter();
	}
	
	public void record(RecordObject obj){
		checkRecordFile();
		
		String record = formatter.format(obj.getFields()) + RecordConfig.RECORD_NEWLINE;
		ByteBuffer buf = ByteBuffer.wrap(record.getBytes());
		//synchronized(recordType){
		try{
			fileChannel.write(buf);
		}catch(Exception e){
			setupAppender();
			try{
				fileChannel.write(buf);
			}catch(Exception e2){
				
			}
			
		}
		//}
	}
	
	public void checkRecordFile(){
		long curTime = System.currentTimeMillis();
		if(isExpireTime(curTime)){
			setupAppender();
		}
	}
	
	public boolean isExpireTime(long time){
		return time >= todayZeroTime + ONE_DATE_MILLIS;
	}
	
	public void setupAppender(){
		Calendar calendar = Calendar.getInstance();
		String dataString = genDataString(calendar);
		String fileName =  dataString + "." + RecordConfig.FILE_PREFIX;
		open(fileName);
		todayZeroTime = genZeroTime(calendar);
	}
	
	public String genDataString(Calendar calendar){
		StringBuffer sb =  new StringBuffer();
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) +1;
		int day = calendar.get(Calendar.DAY_OF_MONTH);
		sb.append(year);
		if(month < 10){
			sb.append("0");
		}
		sb.append(month);
		if(day < 10){
			sb.append("0");
		}
		sb.append(day);
		return sb.toString();
	}
	
	public long genZeroTime(Calendar calendar){
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}
	
	public void open(String fileName){
		close();
		try{
			File path = new File(recordPath);
			if(!path.exists()){
				path.mkdirs();
			}
			fileOut = new FileOutputStream(new File(recordPath,fileName),true);
			fileChannel = fileOut.getChannel();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void close(){
		try{
			if(fileChannel != null && fileChannel.isOpen()){
				fileChannel.close();
			}
			if(fileOut != null){
				fileOut.close();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
